/**
@file

@brief

@author
	GengYong
@revision
	2005/11/05 * Created by GengYong.
*/


#include "InternalService.h"
#include "ConnectionImpl.h"
#include "StdUtility.h"
#include "LogDevice.h"

#include <cassert>

using namespace SAF;

bool InternalServiceModule::Init(IKernel*, IConfig*)
{
	PERFCOUNTER("InternalServiceModule::Init");
	return true;
}

void InternalServiceModule::Release()
{
	PERFCOUNTER("InternalServiceModule::Release");
	return;
}

void InternalServiceModule::Process(IConnection * node, const NetPackage& package)
{
	PERFCOUNTER("InternalServiceModule::Process");

	if (node->Id() == 0)
	{
		switch (package.message.command)
		{
		case KERNEL::INTERNALCOMMAND::CONNECTIONJOIN:
			{
				if (package.buffer.size >= sizeof(KERNEL::INTERNALCOMMAND::CONNECTIONJOIN_tag))
				{
					KERNEL::INTERNALCOMMAND::CONNECTIONJOIN_tag * info = (KERNEL::INTERNALCOMMAND::CONNECTIONJOIN_tag *)package.buffer.data;
					unsigned long size = sizeof(unsigned long);
					unsigned long * pinitstate = (unsigned long*)(node->Restore(SAF::KERNEL::INITSTATENAME, &size));
					if ((pinitstate != 0) && size == sizeof(unsigned long))
					{		
						IConnection * newConnectionNode = new ConnectionImpl(node->Router(), info->connectionId, (*pinitstate), 0);	
						newConnectionNode->Store("#IP#", info->connectionAddr, Util::Util_StringLength(info->connectionAddr) + 1);
						newConnectionNode->Store("#PORT#", &(info->connectionPort), sizeof(info->connectionPort));
						//node->Router()->BindConnection(info->connectionId, newConnectionNode);
					}
					else
					{
						node->Router()->DropConnection(node);
					}
				}
			}
			return;
		case KERNEL::INTERNALCOMMAND::CONNECTIONDROP:
			{
				if (package.buffer.size >= sizeof(KERNEL::INTERNALCOMMAND::CONNECTIONHANDLE_tag))
				{
					KERNEL::INTERNALCOMMAND::CONNECTIONHANDLE_tag * info = (KERNEL::INTERNALCOMMAND::CONNECTIONHANDLE_tag *)package.buffer.data;
					ConnectionImpl * node = (ConnectionImpl*)(info->connectionHandle);
					if (node != 0)
					{
						//if connection droped
						delete node;
					}
				}
			}
			return;
		case KERNEL::INTERNALCOMMAND::CONNECTIONBROKEN:
			{
				if (package.buffer.size >= sizeof(KERNEL::INTERNALCOMMAND::CONNECTIONHANDLE_tag))
				{
					KERNEL::INTERNALCOMMAND::CONNECTIONHANDLE_tag * info = (KERNEL::INTERNALCOMMAND::CONNECTIONHANDLE_tag *)package.buffer.data;
					ConnectionImpl * node = (ConnectionImpl*)(info->connectionHandle);
					if (node != 0)
					{
						//if connection broken
						delete node;
					}
				}
			}
			return;
		//case KERNEL::INTERNALCOMMAND::SETSTATEINVALID:
		//	{
		//		if (package.buffer.size >= sizeof(KERNEL::INTERNALCOMMAND::CONNECTIONHANDLE_tag))
		//		{
		//			KERNEL::INTERNALCOMMAND::CONNECTIONHANDLE_tag * info = (KERNEL::INTERNALCOMMAND::CONNECTIONHANDLE_tag *)package.buffer.data;
		//			ConnectionImpl * node = (ConnectionImpl*)(info->connectionHandle);
		//			{
		//				if (node != 0)
		//				{
		//					//node->m_state = StateBits(-1);
		//				}
		//			}
		//		}
		//	}
		//	return;
		//case KERNEL::INTERNALCOMMAND::TERMINATESVC:
		//	{
		//		throw KERNEL::KERNELEXCEPTION<KERNEL::EXCEPTIONCODE::TERMINATE_REQUEST>();
		//	}
		//	return;
		default:
			{
				SAFLOG("Unknown command %d.", package.message.command);
			}
			return;
		}
	}
	else
	{		
		assert("!Unexpected message @ InternalServiceModule!");
		//node->HostDevice()->SendNetMessage(node->Id(), package.message, &package.buffer, 1);
	}
	return;
}


void InternalServiceModule::OnConnectionIncoming(IConnection * const, void *&)
{
	PERFCOUNTER("InternalServiceModule::OnConnectionIncoming");
}

void InternalServiceModule::OnConnectionOutgoing(IConnection * const, void *&)
{
	PERFCOUNTER("InternalServiceModule::OnConnectionIncoming");
}
